
package com.xlongwei.datetime.handler;

import java.nio.ByteBuffer;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;

import com.networknt.config.JsonMapper;
import com.networknt.rpc.ReflectHandler;
import com.networknt.rpc.router.ServiceHandler;
import com.networknt.utility.HybridUtils;
import com.xlongwei.light4j.util.DateUtil;
import com.xlongwei.light4j.util.HandlerUtil;
import com.xlongwei.light4j.util.HolidayUtil;
import com.xlongwei.light4j.util.HolidayUtil.Holiday;
import com.xlongwei.light4j.util.NumberUtil;
import com.xlongwei.light4j.util.StringUtil;
import com.xlongwei.light4j.util.ZhDate;

import cn.hutool.core.date.Week;
import cn.hutool.core.date.Zodiac;
import io.undertow.server.HttpServerExchange;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@ServiceHandler(id = "xlongwei.com/datetime/reflect/0.0.1")
public class Info extends ReflectHandler {

	public Info() {
		log.info("holidays: {}", HolidayUtil.holidays.size());
	}

	public ByteBuffer info(HttpServerExchange exchange, Object input) {
		Date day = DateUtil.parseNow(HandlerUtil.getParam(exchange, "day"));
		Map<String, Object> map = new LinkedHashMap<>(4);
		info(exchange, day, map);
		return HybridUtils.toByteBuffer(JsonMapper.toJson(map));
	}
	
	public ByteBuffer isworkday(HttpServerExchange exchange, Object input) {
		Date day = DateUtil.parseNow(HandlerUtil.getParam(exchange, "day"));
		Map<String, Object> map = new LinkedHashMap<>(4);
		map.put("isworkday", HolidayUtil.isworkday(day));
		return HybridUtils.toByteBuffer(JsonMapper.toJson(map));
	}
	
	public ByteBuffer convert(HttpServerExchange exchange, Object input) {
		Date day = DateUtil.parseNow(HandlerUtil.getParam(exchange, "day"));
		Map<String, Object> map = new LinkedHashMap<>(4);
		convert(exchange, day, map);
		return HybridUtils.toByteBuffer(JsonMapper.toJson(map));
	}

	private void info(HttpServerExchange exchange, Date day, Map<String, Object> map) {
		map.put("isworkday", HolidayUtil.isworkday(day));
		map.put("isholiday", HolidayUtil.isholiday(day));
		Week week = cn.hutool.core.date.DateUtil.dayOfWeekEnum(day);
		map.put("week", week.getValue() == 1 ? 7 : week.getValue() - 1);
		map.put("isweekend", week == Week.SATURDAY || week == Week.SUNDAY);
		map.put("zodiac", Zodiac.getZodiac(day));
		convert(exchange, day, map);
		holiday(exchange, day, map);
	}

	private void convert(HttpServerExchange exchange, Date day, Map<String, Object> map) {
		if (day != null) {
			ZhDate zhDate = ZhDate.fromDate(day);
			if (zhDate != null) {
				map.put("nongli", zhDate.toString());
				map.put("chinese", zhDate.chinese());
				map.put("ganzhi", zhDate.ganzhi());
				map.put("shengxiao", zhDate.shengxiao());
				map.put("lunarYear", zhDate.getLunarYear());
				map.put("lunarMonth", zhDate.getLunarMonth());
				map.put("lunarDay", zhDate.getLunarDay());
				map.put("isLeapMonth", zhDate.isLeapMonth());
			}
		} else {
			int lunarYear = NumberUtil.parseInt(HandlerUtil.getParam(exchange, "lunarYear"), 2020);
			int lunarMonth = NumberUtil.parseInt(HandlerUtil.getParam(exchange, "lunarMonth"), 1);
			int lunarDay = NumberUtil.parseInt(HandlerUtil.getParam(exchange, "lunarDay"), 28);
			boolean isLeapMonth = NumberUtil.parseBoolean(HandlerUtil.getParam(exchange, "isLeapMonth"), false);
			if (ZhDate.validate(lunarYear, lunarMonth, lunarDay, isLeapMonth)) {
				ZhDate zhDate = new ZhDate(lunarYear, lunarMonth, lunarDay, isLeapMonth);
				day = zhDate.toDate();
				map.put("day", DateUtil.dateFormat.format(day));
				map.put("chinese", zhDate.chinese());
				map.put("ganzhi", zhDate.ganzhi());
				map.put("shengxiao", zhDate.shengxiao());
				map.put("zodiac", Zodiac.getZodiac(day));
			} else {
				map.put("status", "农历日期不支持");
			}
		}
	}

	private void holiday(HttpServerExchange exchange, Date day, Map<String, Object> map) {
		String name = HandlerUtil.getParam(exchange, "name"), year = HandlerUtil.getParam(exchange, "year");
		String plan = StringUtil.isBlank(name) ? null : HolidayUtil.plans.get(year + "." + name);
		if (plan == null) {
			String format = HolidayUtil.dateFormat.format(day);
			Integer flag = HolidayUtil.holidays.get(format);
			if (flag != null) {
				if (flag.intValue() > 0) {
					name = HolidayUtil.nameOf(flag);
					if (StringUtil.hasLength(name)) {
						year = format.substring(0, 4);
						if ("元旦节".equals(name) && "12".equals(format.substring(5, 7))) {
							year = String.valueOf(Integer.parseInt(year) + 1);
						}
						plan = HolidayUtil.plans.get(year + "." + name);
					}
				} else {
					map.put("remark", HolidayUtil.nameOf(-flag) + "调班");
					return;
				}
			} else {
				Holiday guessHoliday = HolidayUtil.guessHoliday(day);
				if (null != guessHoliday) {
					name = guessHoliday.name();
				}
			}
		}
		if (StringUtil.hasLength(name)) {
			map.put("year", year);
			map.put("holiday", name);
			map.put("remark", plan == null ? "" : plan);
		} else {
			String remark = HolidayUtil.guessRemark(day);
			if (StringUtil.hasLength(remark)) {
				map.put("remark", remark);
			}
		}
	}
}
